/*
 * Android Runner is a multiplayer GPS game fully written by Xurxo Mendez Perez
 * 
 * Copyright (C) 2009 Xurxo Mendez Perez
 *   
 * This file is part of Android Runner.
 * 
 * Android Runner is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Android Runner is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Android Runner.  If not, see <http://www.gnu.org/licenses/>.
 */

package es.sonxurxo.androidrunner.model.persistence.game.entity;

import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.AccessType;

import es.sonxurxo.androidrunner.model.persistence.item.entity.Item;
import es.sonxurxo.androidrunner.model.persistence.message.entity.Message;
import es.sonxurxo.androidrunner.model.persistence.player.entity.Player;

/**
 * 
 * @author "Xurxo Mendez Perez"
 *
 */
@Entity
public class Game {

	private long gameId;
	private Calendar startDate;
	private Calendar finishDate;
	private boolean finished = false;
	private int maxPlayers;
	private int pointsToWin;
	private int latitude;
	private int longitude;
	private String city;
	private Set<Item> items = new HashSet<Item>();
	private Set<Player> players = new HashSet<Player>();
	private Set<Message> messages = new HashSet<Message>();
	private Set<FinishedGameRegister> finishedGameRegisters = 
		new HashSet<FinishedGameRegister>();
	
	public Game() {}
	
	public Game(int maxUsers, int pointsToWin, String city) {
		super();
		this.maxPlayers = maxUsers;
		this.pointsToWin = pointsToWin;
		this.city = city;
	}

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO,
            generator="GameIdGenerator")
    @SequenceGenerator(             // It only takes effect for
            name="GameIdGenerator", // databases providing identifier
            sequenceName="GameSeq") // generators.
	public long getGameId() {
		return gameId;
	}

	@OneToMany(mappedBy = "game", fetch = FetchType.LAZY)
	@AccessType(value="field")
	public Set<Message> getMessages() {
		return messages;
	}

	public void setMessages(Set<Message> messages) {
		this.messages = messages;
	}
	
	public void addMessage(Message message) {
		this.messages.add(message);
		message.setGame(this);
	}
	
	public void removeMessage(Message message) {
		this.messages.remove(message);
		message.setGame(null);
	}
	
	public boolean isFinished() {
		return finished;
	}

	public void setFinished(boolean finished) {
		this.finished = finished;
	}
	
	@OneToMany(mappedBy = "game", fetch = FetchType.LAZY)
	public Set<FinishedGameRegister> getFinishedGameRegisters() {
		return finishedGameRegisters;
	}

	public void setFinishedGameRegisters(
			Set<FinishedGameRegister> finishedGameRegisters) {
		this.finishedGameRegisters = finishedGameRegisters;
	}
	
	public void addFinishedGameRegister(FinishedGameRegister finishedGameRegister) {
		this.finishedGameRegisters.add(finishedGameRegister);
		finishedGameRegister.setGame(this);
	}
	
	public void removeFinishedGameRegister(FinishedGameRegister finishedGameRegister) {
		this.finishedGameRegisters.remove(finishedGameRegister);
		finishedGameRegister.setGame(null);
	}

	@OneToMany(mappedBy = "game", fetch = FetchType.LAZY)
	public Set<Player> getPlayers() {
		return players;
	}

	public void setPlayers(Set<Player> players) {
		this.players = players;
	}

	public void addPlayer(Player player) {
		this.players.add(player);
		player.setGame(this);
	}
	
	public void removePlayer(Player player) {
		this.players.remove(player);
		player.setGame(null);
	}
	
	public void setGameId(long gameId) {
		this.gameId = gameId;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Calendar getStartDate() {
		return startDate;
	}

	public void setStartDate(Calendar startDate) {
		this.startDate = startDate;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Calendar getFinishDate() {
		return finishDate;
	}

	public void setFinishDate(Calendar finishDate) {
		this.finishDate = finishDate;
	}

	public int getMaxPlayers() {
		return maxPlayers;
	}

	public void setMaxPlayers(int maxUsers) {
		this.maxPlayers = maxUsers;
	}

	public int getPointsToWin() {
		return pointsToWin;
	}

	public void setPointsToWin(int pointsToWin) {
		this.pointsToWin = pointsToWin;
	}

	public int getLatitude() {
		return latitude;
	}

	public void setLatitude(int latitude) {
		this.latitude = latitude;
	}

	public int getLongitude() {
		return longitude;
	}

	public void setLongitude(int longitude) {
		this.longitude = longitude;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}
	
	public String toString() {
		return new String("Game id = " + this.gameId + 
				";City = " + this.city);
	}

	@OneToMany(mappedBy = "game", fetch = FetchType.LAZY)
	public Set<Item> getItems() {
		return items;
	}

	public void setItems(Set<Item> items) {
		this.items = items;
	}
	
	public void addItem(Item item) {
		this.items.add(item);
		item.setGame(this);
	}
	
	public void removeItem(Item item) {
		this.items.remove(item);
		item.setGame(null);
	}
}
